home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Aminet 4
/
Aminet 4 - November 1994.iso
/
aminet
/
comm
/
net
/
dnet_src.lha
/
dnet
/
amiga
/
client
/
fterm.c
< prev
next >
Wrap
C/C++ Source or Header
|
1990-12-13
|
11KB
|
474 lines
/*
* FTERM.C
*
* DNET (c)Copyright 1988, Matthew Dillon, All Rights Reserved.
*
* FTERM [-Nnet] [port] [-wcapturefile] [-f<font>.<size>] [-c#]
*
* -c# = cooked mode. i.e. -c7 bit 0 convert CR's to LF's keyboard->remote
* bit 1 echo chars locally (half duplex)
* bit 2 received LF->CRLF
*
* CHANGING THE WINDOW SIZE UPDATES S:FTERM.CONFIG
*/
#include "defs.h"
TA Ta = { (ubyte *)"topaz.font", 8 };
ITEXT IText[] = {
{ 0, 1, JAM2, 0, 0, &Ta, (ubyte *)"Flush" },
{ 0, 1, JAM2, 0, 0, &Ta, (ubyte *)"AppendCap" },
{ 0, 1, JAM2, 0, 0, &Ta, (ubyte *)"NewCap" },
{ 0, 1, JAM2, 0, 0, &Ta, (ubyte *)"CloseCap" },
{ 0, 1, JAM2, 0, 0, &Ta, (ubyte *)"Paste" }
{ 0, 1, JAM2, 0, 0, &Ta, (ubyte *)"FTerm" }
};
ITEM Item[] = {
{ &Item[1], 0, 0, 100, 10, ITEMTEXT|COMMSEQ|ITEMENABLED|HIGHCOMP, 0, (APTR)&IText[0], NULL, 'o' },
{ &Item[2], 0,10, 100, 10, ITEMTEXT|COMMSEQ|ITEMENABLED|HIGHCOMP, 0, (APTR)&IText[1], NULL, 'a' },
{ &Item[3], 0,20, 100, 10, ITEMTEXT|COMMSEQ|ITEMENABLED|HIGHCOMP, 0, (APTR)&IText[2], NULL, 'n' },
{ &Item[4], 0,30, 100, 10, ITEMTEXT|COMMSEQ|ITEMENABLED|HIGHCOMP, 0, (APTR)&IText[3], NULL, 'c' },
{ &Item[5], 0,40, 100, 10, ITEMTEXT|COMMSEQ|ITEMENABLED|HIGHCOMP, 0, (APTR)&IText[4], NULL, 'p' },
{ NULL , 0,50, 100, 10, ITEMTEXT|COMMSEQ|ITEMENABLED|HIGHCOMP, 0, (APTR)&IText[5], NULL, 'f' }
};
MENU Menu[] = {
{ NULL , 0, 0, 100, 10+50, MENUENABLED, "Control", &Item[0] }
};
ubyte Title[80];
NW Nw = {
0, 0, 320, 200, -1, -1,
NEWSIZE|CLOSEWINDOW|MENUPICK,
WINDOWSIZING|WINDOWDRAG|WINDOWDEPTH|WINDOWCLOSE|NOCAREREFRESH|ACTIVATE,
NULL, NULL, Title, NULL, NULL,
32, 32, -1, -1, WBENCHSCREEN
};
char Font[64] = { "topaz.font" };
short FontSize = 8;
WIN *Win;
extern int Enable_Abort;
char Buf[512];
char Term[64];
char Cc;
char Cooked; /* bit 0 = cooked, bit 1 = local echo */
char IgnoreNS;
struct IntuitionBase *IntuitionBase;
struct GfxBase *GfxBase;
void OpenConsole ARGS((WIN *, IOCON **, IOCON **));
void HandleIoctl ARGS((short, short, char, WIN *, IOCON *));
void CloseConsole ARGS((IOCON *, IOCON *));
void setsize ARGS((IOCON *, void *, WIN *));
void parseopts ARGS((char *, char **, char **, short *, short *, short *, short *));
void SaveConfig();
void LoadConfig();
void main ARGS((int, char **));
int
brk()
{
return(0);
}
void
main(ac, av)
char *av[];
{
void *chan;
long imask, conmask, dmask, mask;
IOCON *iocr, *iocw;
char notdone = 1;
char portspec = 0;
char *host = NULL;
char *capfile = NULL;
FILE *capfi = NULL;
uword port = PORT_IALPHATERM;
FONT *font = NULL;
onbreak(brk);
sprintf(Title, "FTerm V%s%s", VERSION, FTERM_VERSION);
strcpy(Term, Title);
strcat(Title, " opening, wait ...");
{
char *str = av[0];
for (str = str + strlen(str); str >= av[0]; --str) {
if (*str == '/' || *str == ':')
break;
}
++str;
if ((*str | 0x20) == 'b') /* bbsterm instead of fterm */
port = PORT_BBS;
}
LoadConfig();
{
short i;
for (i = 1; i < ac; ++i) {
char *ptr = av[i];
if (*ptr == '-') {
while (*++ptr) {
switch(*ptr) {
case 'N':
host = ptr + 1;
ptr = "\0";
break;
case 'w':
capfile = ptr + 1;
ptr = "\0";
break;
case 'c':
Cooked = atoi(ptr + 1);
ptr = "\0";
break;
case 'f': /* topaz.8, etc... */
{
char *str;
for (str = ptr + 1; *str && *str != '.'; ++str);
if (*str == '.') {
*str++ = 0;
strcpy(Font, ptr);
FontSize = atoi(str);
}
}
break;
default:
printf("Unknown option: '%c'\n", *ptr);
break;
}
}
} else {
portspec = 1;
port = atoi(ptr);
}
}
}
if (capfile)
capfi = fopen(capfile, "a");
if (portspec)
printf("Using port %ld\n", port);
#ifndef LATTICE
Enable_Abort = 0;
#endif
IntuitionBase = (struct IntuitionBase *)OpenLibrary("intuition.library", 0);
GfxBase = (struct GfxBase *)OpenLibrary("graphics.library", 0);
font = GetFont(Font, FontSize);
Win = OpenWindow(&Nw);
if (Win == NULL)
goto e1;
if (font) {
SetFont(Win->RPort, font);
SetRast(Win->RPort, 0);
RefreshWindowFrame(Win);
}
OpenConsole(Win, &iocr, &iocw);
if (iocr == NULL || iocw == NULL)
goto e3;
/*
* We delay here to allow DNET to go through its RESTART sequence
* (when DNET automatically runs FTERM, it does so to quickly).
* Such a hack!
*/
Delay(50 * 4);
chan = DOpen(host, port, 20, 15);
if (!chan) {
puts("Unable to connect");
goto e3;
}
DQueue(chan, 32);
SetMenuStrip(Win, Menu);
SetWindowTitles(Win, Term, (char *)-1);
imask = 1 << Win->UserPort->mp_SigBit;
dmask = 1 << ((PORT *)chan)->mp_SigBit;
conmask = 1 << iocr->io_Message.mn_ReplyPort->mp_SigBit;
iocr->io_Data = (APTR)&Cc;
iocr->io_Length = 1;
SendIO(iocr);
setsize(iocw, chan, Win);
while (notdone) {
mask = Wait(imask|dmask|conmask);
if (mask & imask) {
IMESS *im;
while (im = (IMESS *)GetMsg(Win->UserPort)) {
switch(im->Class) {
case NEWSIZE:
Nw.LeftEdge = Win->LeftEdge;
Nw.TopEdge = Win->TopEdge;
Nw.Width = Win->Width;
Nw.Height = Win->Height;
if (IgnoreNS) {
--IgnoreNS;
setsize(iocw, NULL, Win);
} else {
setsize(iocw, chan, Win);
}
break;
case CLOSEWINDOW:
notdone = 0;
break;
case MENUPICK:
switch((uword)((MENUNUM(im->Code)<<8)|ITEMNUM(im->Code))) {
case 0x0000: /* menu 0 item 0 */
DIoctl(chan, CIO_FLUSH, 0, 0);
break;
case 0x0001: /* menu 0 item 1 */
if (capfi)
fclose(capfi);
capfi = fopen("ram:capture", "a");
break;
case 0x0002:
if (capfi)
fclose(capfi);
capfi = fopen("ram:capture", "w");
break;
case 0x0003: /* menu 0 item 2 */
if (capfi)
fclose(capfi);
capfi = NULL;
break;
case 0x0004: /* menu 0 item 3 */
{
FILE *fi;
long n;
if (fi = fopen("ram:paste", "r")) {
while ((n = fread(Buf, 1, sizeof(Buf), fi)) > 0) {
DWrite(chan, Buf, n);
}
fclose(fi);
}
}
break;
case 0x0005:
Execute("RUN <NIL: >NIL: fterm", NULL, NULL);
break;
case 0x0100: /* menu 1 item 0 */
break;
}
}
ReplyMsg((MSG *)im);
}
}
if (mask & dmask) {
int n;
if ((n = DNRead(chan, Buf, sizeof(Buf))) > 0) {
iocw->io_Data = (APTR)Buf;
iocw->io_Length = n;
DoIO(iocw);
if (capfi)
fwrite(Buf, n, 1, capfi);
} else if (n == -2) {
short val;
short cmd;
char aux;
cmd = DGetIoctl(chan, &val, &aux);
HandleIoctl(cmd, val, aux, Win, iocw);
if (cmd == CIO_MODE) {
if (val)
SetWindowTitles(Win, "(Cooked)", (char *)-1);
else
SetWindowTitles(Win, "(Raw)", (char *)-1);
}
} else if (n < 0) {
notdone = 0;
}
}
if (mask & conmask) {
if (CheckIO(iocr)) {
WaitIO(iocr);
if (Cooked & 2) { /* Local Echo */
iocw->io_Data = (APTR)&Cc;
iocw->io_Length = 1;
DoIO(iocw);
}
if ((Cooked & 1) && Cc == 13) {
Cc = 10;
iocw->io_Data = (APTR)&Cc;
iocw->io_Length = 1;
DoIO(iocw);
}
DWrite(chan, &Cc, 1);
iocr->io_Data = (APTR)&Cc;
iocr->io_Length = 1;
SendIO(iocr);
}
}
}
AbortIO(iocr);
WaitIO(iocr);
SetWindowTitles(Win, "Closing...", (char *)-1);
DClose(chan);
e3: CloseConsole(iocr,iocw);
if (font) {
SetFont(Win->RPort, Win->WScreen->RastPort.Font);
CloseFont(font);
}
{
Nw.LeftEdge = Win->LeftEdge;
Nw.TopEdge = Win->TopEdge;
Nw.Width = Win->Width;
Nw.Height = Win->Height;
SaveConfig();
}
CloseWindow(Win);
e1: CloseLibrary((LIB *)IntuitionBase);
CloseLibrary((LIB *)GfxBase);
if (capfi)
fclose(capfi);
}
void
OpenConsole(win, piocr, piocw)
IOCON **piocr, **piocw;
WIN *win;
{
PORT *port;
static IOCON iocr, iocw;
int error;
port = CreatePort(NULL, 0);
iocr.io_Command = CMD_READ;
iocr.io_Data = (APTR)win;
iocr.io_Message.mn_Node.ln_Type = NT_MESSAGE;
iocr.io_Message.mn_ReplyPort = port;
error = OpenDevice("console.device", 0, &iocr, 0);
if (!error) {
iocw = iocr;
iocw.io_Command = CMD_WRITE;
*piocr = &iocr;
*piocw = &iocw;
} else {
*piocr = *piocw = NULL;
}
}
void
CloseConsole(iocr, iocw)
IOCON *iocr;
IOCON *iocw;
{
IOCON *tmp = (iocr) ? iocr : iocw;
if (tmp) {
CloseDevice(tmp);
DeletePort(tmp->io_Message.mn_ReplyPort);
}
}
void
setsize(iocw, chan, win)
IOCON *iocw;
void *chan;
WIN *win;
{
struct ConUnit *cu = (struct ConUnit *)iocw->io_Unit;
static char IStr[] = { "\033c\23320l\233t\233u" };
if (Cooked & 4)
IStr[5] = 'h';
else
IStr[5] = 'l';
iocw->io_Data = (APTR)IStr;
iocw->io_Length = sizeof(IStr) - 1;
DoIO(iocw);
if (chan) {
DIoctl(chan, CIO_SETROWS, (uword)(cu->cu_YMax+1), 0);
DIoctl(chan, CIO_SETCOLS, (uword)(cu->cu_XMax+1), 0);
}
sprintf(Term, "FTERM %ld x %ld", cu->cu_YMax+1, cu->cu_XMax+1);
SetWindowTitles(win, Term, (char *)-1);
}
void
HandleIoctl(cmd, val, aux, win, iocw)
short cmd, val;
char aux;
WIN *win;
IOCON *iocw;
{
static short saverows;
short height, width;
short dx, dy;
switch(cmd) {
case CIO_MODE:
Cooked = val;
break;
case CIO_SETROWS:
saverows = val;
break;
case CIO_SETCOLS:
width = val * win->RPort->TxWidth + win->BorderLeft + win->BorderRight;
height= saverows * win->RPort->TxHeight + win->BorderTop + win->BorderBottom;
dx = win->WScreen->Width - (win->LeftEdge + width);
if (dx > 0)
dx = 0;
if (-dx > win->LeftEdge) {
dx = -win->LeftEdge;
width = win->WScreen->Width;
}
dy = win->WScreen->Height - (win->TopEdge + height);
if (dy > 0)
dy = 0;
if (-dy > win->TopEdge) {
dy = -win->TopEdge;
height = win->WScreen->Height;
}
if (dx || dy) {
MoveWindow(win, dx, dy);
}
if (win->Width != width || win->Height != height) {
SizeWindow(win, width - win->Width, height - win->Height);
++IgnoreNS;
}
break;
}
}
void
loadConfig()
{
FILE *fi;
if (fi = fopen("S:FTerm.config", "r")) {
fread(&Nw, sizeof(Nw), 1, fi);
fread(Font, sizeof(Font), 1, fi);
fread(&FontSize, sizeof(FontSize), 1, fi);
fclose(fi);
}
}
void
SaveConfig()
{
FILE *fi;
if (fi = fopen("S:FTerm.config", "w")) {
fwrite(&Nw, sizeof(Nw), 1, fi);
fwrite(Font, sizeof(Font), 1, fi);
fwrite(&FontSize, sizeof(FontSize), 1, fi);
fclose(fi);
}
}